﻿using NDK.Module.Model;
using NDK.Motion.BLL;
using NDK.Motion.MachineManager;
using NDK.Motion.Monitor;
using NDK.Motion.Sys;
using System;
using System.Collections.Concurrent;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading;

namespace NDK.Module.StationLogic
{
    public class Station_下料翻转 : StationLogic
    {
        #region 通用
        public override event PropertyChangedEventHandler PropertyChanged;

        public static Station_下料翻转 Instance = new Station_下料翻转();
        public Stopwatch SunWay15 = new Stopwatch();
        public string StationName = "Station15下料翻转";


        private int RobotPickCount;
        private bool[] ArrayHoleIsHave;
        public ConcurrentQueue<bool[]> QueueHoleIsHave;

        private string[] ArrayAddr_机械手允许取料;
        private string[] ArrayAddr_机械手取料有料信号;
        private string[] ArrayAddr_机械手取料结果;
        private string[] ArrayAddr_机械手允许离开;
        private PLCInPut[] ArrayAddr_机械手取料到位;
        private PLCInPut[] ArrayAddr_机械手离开完成;
        private int i = 0;

        //步骤字段、属性
        private StationStep _Step = StationStep.轴移动至放料接近位;
        [Monitor(Description = "当前步骤")]
        public StationStep Step
        {
            get
            {
                return _Step;
            }
            set
            {
                if (_Step != value)
                {
                    _Step = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(value.ToString()));
                }
            }
        }
        #endregion

        /// <summary>
        /// 工站初始化
        /// </summary>
        public override void Init()
        {
            base.Init();
            RobotPickCount = 0;
            logBaseInfo = "下料翻转流程";
            Step = StationStep.轴移动至放料接近位;
            ArrayAddr_机械手取料到位 = new PLCInPut[1] { PLCInPut.取料到位1/*, PLCInPut.取料到位2 */};
            ArrayAddr_机械手离开完成 = new PLCInPut[1] { PLCInPut.取料离开1/*, PLCInPut.取料离开2*/ };
            ArrayAddr_机械手允许取料 = new string[1] { Common.PLCAdr.DicOutPutBool[PLCOutPutBool.下料取料允许1]/*, Common.PLCAdr.DicOutPutBool[PLCOutPutBool.下料取料允许2]*/ };
            ArrayAddr_机械手允许离开 = new string[] { Common.PLCAdr.DicOutPutBool[PLCOutPutBool.下料离开允许1]/*, Common.PLCAdr.DicOutPutBool[PLCOutPutBool.下料离开允许2]*/ };
            ArrayAddr_机械手取料有料信号 = new string[2] { Common.PLCAdr.DicOutPutBool[PLCOutPutBool.穴1有料], Common.PLCAdr.DicOutPutBool[PLCOutPutBool.穴2有料] };
            ArrayAddr_机械手取料结果 = new string[2] { Common.PLCAdr.DicOutPutInt[PLCOutPutInt.穴1结果], Common.PLCAdr.DicOutPutInt[PLCOutPutInt.穴2结果] };
            QueueHoleIsHave = new ConcurrentQueue<bool[]>();
            SunWay15.Start();
        }

        public override void ActionProcess()
        {
            try
            {
                switch (Step)
                {
                    case StationStep.轴移动至放料接近位:

                        if (!Common.PLCAdr.DicInPutValue[PLCInPut.下料安全信号]) { break; }
                        if (MotionControl.AxesMove(Machine.pos_取料接近位_下料翻转工位))
                        {
                            SignalRequest = true;
                            Step = StationStep.等待上工位允许取料;
                        }
                        break;

                    case StationStep.等待上工位允许取料:
                        if (Station_PPG测量.Instance.SignalComplete)
                        {
                            Step = StationStep.轴运行至取料位;
                        }
                        break;

                    case StationStep.轴运行至取料位:
                        if (MotionControl.AxesMove(Machine.pos_取料位_下料翻转工位))
                        {
                            QueueHoleIsHave.TryDequeue(out ArrayHoleIsHave);
                            Step = StationStep.打开真空吸;
                        }
                        break;

                    case StationStep.打开真空吸:
                        if (VacuumMethod(true, (Machine.do_翻转真空吸1, Machine.di_翻转真空检测1, ArrayHoleIsHave[0]), (Machine.do_翻转真空吸2, Machine.di_翻转真空检测2, ArrayHoleIsHave[1])))
                        {
                            Thread.Sleep(300);
                            Step = StationStep.轴运动至放料位;
                        }
                        break;

                    case StationStep.运动到真空确认位:
                        if (MotionControl.AxesMove(Machine.pos_真空确认位_下料翻转工位))
                        {
                            Step = StationStep.再次确认真空吸;
                        }
                        break;

                    case StationStep.再次确认真空吸:
                        if (VacuumMethod(true, (Machine.do_翻转真空吸1, Machine.di_翻转真空检测1, ArrayHoleIsHave[0]), (Machine.do_翻转真空吸2, Machine.di_翻转真空检测2, ArrayHoleIsHave[1])))
                        {
                            Step = StationStep.轴运动至放料位;
                        }
                        break;

                    case StationStep.轴运动至放料位:
                        if (!Common.PLCAdr.DicInPutValue[PLCInPut.下料安全信号]) { break; }
                        if (MotionControl.AxesMove(Machine.pos_放料位_下料翻转工位))
                        {
                            SignalRequest = false;
                            int count = (ArrayHoleIsHave[0] ? 1 : 0) + (ArrayHoleIsHave[1] ? 1 : 0);
                            if (DataProcess.Instance.DataResult.Count < count)
                                break;
                            if (ArrayHoleIsHave[0])
                            {
                                DataProcess.Instance.DataResult.TryDequeue(out int result);
                                Common.OmronPLC.Write(ArrayAddr_机械手取料结果[0], (short)result);
                                UILog_Alert($"[{logBaseInfo}] 发送取料结果1: {result}");
                            }
                            if (ArrayHoleIsHave[1])
                            {
                                DataProcess.Instance.DataResult.TryDequeue(out int result);
                                Common.OmronPLC.Write(ArrayAddr_机械手取料结果[1], (short)result);
                                UILog_Alert($"[{logBaseInfo}] 发送取料结果2: {result}");
                            }
                            Common.OmronPLC.Write(ArrayAddr_机械手取料有料信号[0], ArrayHoleIsHave[0]);
                            Common.OmronPLC.Write(ArrayAddr_机械手取料有料信号[1], ArrayHoleIsHave[1]);
                            UILog_Alert($"[{logBaseInfo}] 发送取料有无: {ArrayHoleIsHave[0]},{ArrayHoleIsHave[1]}");
                            Step = StationStep.判断工位是否有料;
                        }
                        break;

                    case StationStep.判断工位是否有料:
                        if (ArrayHoleIsHave[0] || ArrayHoleIsHave[1] || Common.IsEmptyModel)
                        {
                            Step = StationStep.允许机械手取料;
                        }

                        else
                        {
                            Step = StationStep.轴移动至放料接近位;
                        }
                        break;

                    case StationStep.允许机械手取料:
                        if (PLCWriteMethod(logBaseInfo, (ArrayAddr_机械手允许取料[0], true, null)))
                        {
                            Step = StationStep.等待机械手取料;
                        }
                        break;

                    case StationStep.等待机械手取料:
                        if (Common.PLCAdr.DicInPutValue[ArrayAddr_机械手取料到位[0]])
                        {
                            Step = StationStep.关闭真空吸;
                        }
                        break;

                    case StationStep.关闭真空吸:
                        Machine.VacuumArray_翻转真空吸[0].OFF();
                        Machine.VacuumArray_翻转真空吸[1].OFF();
                        Machine.VacuumArray_翻转真空破[0].ON();
                        Machine.VacuumArray_翻转真空破[1].ON();
                        Thread.Sleep(200);
                        Machine.VacuumArray_翻转真空破[0].OFF();
                        Machine.VacuumArray_翻转真空破[1].OFF();
                        Step = StationStep.允许机械手离开;
                        break;

                    case StationStep.允许机械手离开:
                        if (PLCWriteMethod(logBaseInfo, (ArrayAddr_机械手允许离开[0], true, null)))
                        {
                            Step = StationStep.等待机械手离开;
                        }
                        break;

                    case StationStep.等待机械手离开:

                        if (Common.PLCAdr.DicInPutValue[ArrayAddr_机械手离开完成[0]])
                        {
                            Step = StationStep.关闭交互信号;
                        }
                        break;

                    case StationStep.关闭交互信号:
                        if (PLCWriteMethod(logBaseInfo, (ArrayAddr_机械手允许取料[0], false, null),
                                                        (ArrayAddr_机械手允许离开[0], false, null),
                                                        (ArrayAddr_机械手取料有料信号[0], false, null),
                                                        (ArrayAddr_机械手取料有料信号[1], false, null)))
                        {
                            Common.OmronPLC.Write(ArrayAddr_机械手取料结果[0], (short)0);
                            Common.OmronPLC.Write(ArrayAddr_机械手取料结果[1], (short)0);
                            Step = StationStep.等待机械手关闭信号;
                            if (Common.IsClearModel && Common.TurnTableNone && !Station_下置激光.Instance.IsHaveProduct && Station_PPG测量.Instance.QueueHoleIsHave.Count < 1
                                 && Station_下料搬运.Instance.QueueHoleIsHave.Count < 1)
                                if (i < 5)
                                {
                                    i++;
                                    Step = StationStep.关闭交互信号;
                                    break;
                                }
                                else
                                {
                                    Common.OmronPLC.Write(Common.PLCAdr.DicOutPutBool[PLCOutPutBool.量测清料完成], true);
                                    i = 0;
                                }
                        }
                        break;

                    case StationStep.等待机械手关闭信号:
                        if (!Common.PLCAdr.DicInPutValue[ArrayAddr_机械手取料到位[0]] && !Common.PLCAdr.DicInPutValue[ArrayAddr_机械手离开完成[0]])
                        {
                            //RobotPickCount++;
                            Step = StationStep.轴移动至放料接近位;
                        }
                        break;

                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
                MachineStatusManager.CurrentMachineStatus = MachineStatus.Alarm;
                UILog_Error($"[{logBaseInfo}] {ex.Message}");
            }
        }

        public override void EmptyActionProcess()
        {
            ActionProcess();
        }

        public override void GRRActionProcess()
        {
            ActionProcess();
        }

        public enum StationStep
        {
            轴移动至放料接近位,
            等待上工位允许取料,
            轴运行至取料位,
            打开真空吸,
            运动到真空确认位,
            再次确认真空吸,
            轴运动至放料位,
            判断工位是否有料,
            允许机械手取料,
            等待机械手取料,
            关闭真空吸,
            允许机械手离开,
            等待机械手离开,
            判断取料次数,
            关闭交互信号,
            等待机械手关闭信号
        }
    }

}
